package com.minio.learning.springminio.util;

import com.minio.learning.springminio.entity.FileInfo;
import io.minio.*;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteError;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * @author YanXxx
 */
@Slf4j
public class MinioUtil {

    private static final MinioClient MINIO_CLIENT = SpringUtils.getBean(MinioClient.class);


    /**
     * 创建一个桶
     */
    public static void createBucket(String bucket) throws Exception {
        boolean found = MINIO_CLIENT.bucketExists(BucketExistsArgs.builder().bucket(bucket).build());
        if (!found) {
            MINIO_CLIENT.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
        }
    }

    /**
     * 上传一个文件
     */
    public static String uploadFile(String baseDir, String bucketName, String fileName, MultipartFile file) throws Exception {
        PutObjectArgs args = PutObjectArgs.builder()
                .bucket(bucketName)
                .object(baseDir + '/' + fileName)
                .stream(file.getInputStream(), file.getSize(), -1)
                .contentType(file.getContentType())
                .build();
        MINIO_CLIENT.putObject(args);
        return fileName;
    }

    /**
     * 列出所有的桶
     */
    public static List<String> listBuckets() throws Exception {
        List<Bucket> list = MINIO_CLIENT.listBuckets();
        List<String> names = new ArrayList<>();
        list.forEach(b -> {
            names.add(b.name());
        });
        return names;
    }

    /**
     * 列出一个桶中的所有文件和目录
     */
    public static List<FileInfo> listFiles(String bucket) throws Exception {
        Iterable<Result<Item>> results = MINIO_CLIENT.listObjects(
                ListObjectsArgs.builder().bucket(bucket).recursive(true).build());

        List<FileInfo> infos = new ArrayList<>();
        results.forEach(r -> {
            FileInfo info = new FileInfo();
            try {
                Item item = r.get();
                info.setFilename(item.objectName());
                info.setDirectory(item.isDir());
                infos.add(info);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        return infos;
    }

    /**
     * 下载一个文件
     */
    public static InputStream download(String bucket, String objectName) throws Exception {
        return MINIO_CLIENT.getObject(
                GetObjectArgs.builder().bucket(bucket).object(objectName).build());
    }

    /**
     * 删除一个桶
     */
    public static void deleteBucket(String bucket) throws Exception {
        MINIO_CLIENT.removeBucket(RemoveBucketArgs.builder().bucket(bucket).build());
    }

    /**
     * 删除一个对象
     */
    public static void deleteObject(String bucket, String objectName) throws Exception {
        MINIO_CLIENT.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(objectName).build());
    }

    /**
     * 删除一个或多个对象
     */
    public static void deleteObjects(String bucketName, List<String> filePaths) throws Exception {
        List<DeleteObject> list = new ArrayList<>();
        for (String filePath : filePaths) {
            list.add(new DeleteObject(filePath));
        }
        Iterable<Result<DeleteError>> iterable = MINIO_CLIENT.removeObjects(
                RemoveObjectsArgs.builder().bucket(bucketName).objects(list).build()
        );
        for (Result<DeleteError> result : iterable) {
            DeleteError error = result.get();
            log.info("minio删除错误->bucketName={},objectName={},message={}", error.bucketName(), error.objectName(), error.message());
        }
    }
}